package com.rbn.stockmobiledevices.salidas.internal;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.transaction.annotation.Transactional;

import com.rbn.stockmobiledevices.clientes.Cliente;
import com.rbn.stockmobiledevices.clientes.ClienteManager;
import com.rbn.stockmobiledevices.clientes.internal.HibernateClienteManager;
import com.rbn.stockmobiledevices.dispositivos.Dispositivo;
import com.rbn.stockmobiledevices.dispositivos.DispositivoManager;
import com.rbn.stockmobiledevices.dispositivos.internal.HibernateDispositivoManager;
import com.rbn.stockmobiledevices.salidas.Venta;
import com.rbn.stockmobiledevices.salidas.VentaManager;
import com.rbn.stockmobiledevices.utils.AutoCompleteElement;

public class HibernateVentaManager implements VentaManager {

	private SessionFactory sessionFactory;

	public HibernateVentaManager(SessionFactory sessionFactory) {
		this.sessionFactory = sessionFactory;
	}

	@Transactional(readOnly = true)
	@SuppressWarnings("unchecked")
	public List<Venta> getAll() {
		return getCurrentSession().createQuery("from Venta").list();
	}

	@Transactional(readOnly = true)
	public Venta getById(Long imei) {
		return (Venta) getCurrentSession().load(Venta.class, imei);
	}

	@Transactional
	public void update(Venta venta) {
		getCurrentSession().update(venta);
	}

	@Transactional
	public void remove(Venta venta) {
		getCurrentSession().delete(venta);

	}

	@Transactional
	public boolean remove(long imei) {
		Venta e = this.getById(imei);
		if(e==null)
			return false;
		getCurrentSession().delete(e);
		return true;
	}

	@Transactional
	public void save(Venta venta) {
		getCurrentSession().save(venta);
	}

	@SuppressWarnings("unchecked")
	@Transactional(readOnly = true)
	public List<Venta> getPaginadoVentas(Integer startPosition,
			Integer pageSize, Long imei, String dispositivo,
			Integer cliente, Date fecha) {
		Session session = getCurrentSession();
		String hlqQuery = "from Venta v";

		String whereClause = "";
		if((imei!=null && imei!=0) || (dispositivo !=null && dispositivo.length()>0) || cliente!=null || fecha!=null){
			hlqQuery += " where ";
		
			if (imei != null && imei!=0) {
				whereClause += "and  v.imei = :imei ";
			}
			if(dispositivo !=null && dispositivo.length()>0){
				whereClause += "and  v.dispositivo.modelo like :dispositivo ";
			}
			if(cliente != null){
				whereClause += "and  v.cliente.id = :cliente ";
			}
			if(fecha != null){
				whereClause += "and  v.fechaVenta between :fecha_desde and :fecha_hasta ";
			}
			
			whereClause = whereClause.substring(whereClause.indexOf("and ")+4 ,whereClause.length());
			hlqQuery += whereClause;
		}
		
		hlqQuery += " order by v.fechaVenta desc, v.imei";
		Query q = session.createQuery(hlqQuery);
		
		if (imei != null && imei != 0) {
			q.setLong("imei", imei);
		}
		if(dispositivo !=null && dispositivo.length()>0){
			q.setString("dispositivo", "%"+dispositivo+"%");
		}
		if(cliente != null){
			q.setLong("cliente", cliente);
		}
		if(fecha != null){
			Date fecha_desde = null;
			Date fecha_hasta = null;
			GregorianCalendar cal = new GregorianCalendar();
			cal.setTime(fecha);
			cal.set(Calendar.HOUR, 0);
			cal.set(Calendar.MINUTE, 0);
			cal.set(Calendar.SECOND, 0);
			cal.set(Calendar.MILLISECOND, 0);
			
			fecha_desde = cal.getTime();
			cal.add(Calendar.HOUR, 23);
			cal.add(Calendar.MINUTE, 59);
			cal.add(Calendar.SECOND, 59);
			
			fecha_hasta = cal.getTime(); 
			q.setDate("fecha_desde", fecha_desde);
			q.setDate("fecha_hasta", fecha_hasta);
		}
		
		if(startPosition!=null && pageSize!=null){
			q.setFirstResult(startPosition);
			q.setMaxResults(pageSize);
		}
		return q.list();
	}

	@Transactional(readOnly = true)
	public Dispositivo getDispositivoByCodigo(String codigo) {
		DispositivoManager dispositivoMgr = new HibernateDispositivoManager(sessionFactory);
		return dispositivoMgr.getById(codigo);
	}

	@Transactional(readOnly = true)
	public Cliente getClienteById(int id) {
		ClienteManager clienteMgr = new HibernateClienteManager(sessionFactory);
		return clienteMgr.getById(id);
	}
	
	@Transactional(readOnly = true)
	public List<AutoCompleteElement> getClienteOptionsByModelo(String search) {
		ClienteManager clienteMgr = new HibernateClienteManager(sessionFactory);
		List<Cliente> clientes = clienteMgr.getByNombre(search);
		
		List<AutoCompleteElement> elements = new ArrayList<AutoCompleteElement>();
		AutoCompleteElement element = null;
		for (Cliente cliente : clientes) {
			element = new AutoCompleteElement(String.valueOf(cliente.getId()), cliente.getNombre());
			elements.add(element);
		}
		return elements;
	}
	
	protected Session getCurrentSession() {
		return sessionFactory.getCurrentSession();
	}
}